//= require "list"
//= require "listview_ungrouped"

/* MusicNet Alignment Tool
 *
 * Copyright (c) 2010 Joe Lambert
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *  
 */

/** section: alignment
 * class UngroupedList < ListContainer
 * 
 * Specialised container for list of Ungrouped items 
 **/

var UngroupedList = Class.create(ListContainer, {
	initialize: function($super, options)
	{
		this.tag = "ungrp";
		this.id = "ungroupedlist";
		this.trashed = false;
		$super(options);
		
		this.toggle = Builder.node('ul', {className: 'toggle'}, [
			Builder.node('li', {className: 'verified first selected'}, 'Ungrouped'),
			Builder.node('li', {className: 'unverified last'}, 'Trashed')
		]);
		
		this.toggle.observe('click', function(event){
			event.stop();
			this.toggleTrashed();
		}.bindAsEventListener(this));
		
		this.bodyDiv.insert(this.toggle);
		
		document.observe('group:removed', function(event){
			if(event && event.memo)
			{
				var a2z = event.memo;
				
				if(this.currentPage == a2z)
				{
					this.loadData(this.currentPage);
				}
			}
		}.bindAsEventListener(this));
		
		document.observe('trash:reload', function(event){
			if(this.trashed)
				this.loadData(this.currentPage);
		}.bindAsEventListener(this));
	},

/**
 * UngroupedList#toggleTrashed() -> null
 * 
 * Toggle the visibility of trashed items
 **/
	
	toggleTrashed: function()
	{
		var selected = this.toggle.getElementsBySelector(".selected")[0];
		
		if(selected.hasClassName('verified'))
		{
			this.trashed = true;
			selected.removeClassName('selected');
			this.toggle.getElementsBySelector(".unverified")[0].addClassName('selected');
		}
		else
		{
			this.trashed = false;
			selected.removeClassName('selected');
			this.toggle.getElementsBySelector(".verified")[0].addClassName('selected');
		}
		
		this.loadData(this.currentPage);
	},

/**
 * UngroupedList#loadData(page, callback) -> null
 * - page (String): The A2Z page to load
 * - callback (function): The function to perform once the load has completed
 * 
 * Load the items from the given page
 **/
	
	loadData: function(page, callback)
	{
		this.listView.setLoading();
		this.updateA2Z();

		new Ajax.Request(window.location.pathname+this.options.dataURL+(this.trashed ? '/trashed' : ''), {
			method: 'get',
			parameters: 'a2z='+page,
			onSuccess: function(transport) {
				this.data = transport.responseJSON.data;
				this.refresh();
				
				if(Object.isFunction(callback))
					callback.bind(this)();
			}.bind(this)
		});
	},
	
	keyPress: function($super, event)
	{
		if(event.keyCode == 71 && !event.ctrlKey && !event.shiftKey) // g
		{
			this.groupSelected();	
			event.stop();
		}
		if(event.keyCode == 83 && !event.ctrlKey && !event.shiftKey) // s
		{
			this.createSingleItemGroups();	
			event.stop();
		}
		if(event.keyCode == 85) // u
		{
			if(this.trashed)
			{
				this.untrashSelected();
			}
		}
		else
			$super(event);
	},

	trashSelected: function()
	{
		var selected = this.listView.getSelectedIndexes();
				
		var ids = new Array();
		
		for(var index in selected)
		{					
			if(selected[index] && !this.listView.list.childElements()[index].hasClassName('grouped'))
			{
				ids.push(this.data[index].id);
				
				this.listView.list.childElements()[parseInt(index)].setLoading();
			}
		}
		
		var ids_string = "";
		ids.each(function(id) {
			ids_string += "&id[]="+id;
		});
		
		var scrollTop = this.listView.surface.scrollTop;
		
		var curElement = this.listView.getSelectedElements()[0];
		
		var selectedElement = curElement.previous();
		
		if(!selectedElement)
			selectedElement = curElement.next();
			
		if(!selectedElement)
			selectedElement = false;
		else
			selectedElement = selectedElement.getID();
		
		new Ajax.Request(window.location.pathname+"ajax/trash_item", {
			method: 'get',
			parameters: ids_string,
			onSuccess: function(transport) {
				this.loadData(this.currentPage, function() {
					this.listView.surface.scrollTop = scrollTop;
					
					var elem = $$("li."+selectedElement);
					
					if(elem.length)
						this.listView.selectRow($$("li."+selectedElement)[0]);
				});
				
			}.bind(this)
		});
	},

/**
 * UngroupedList#untrashSelected() -> null
 * 
 * Restore the selected trashed items
 **/
	
	untrashSelected: function()
	{
		var selected = this.listView.getSelectedIndexes();
				
		var ids = new Array();
		
		for(var index in selected)
		{					
			if(selected[index] && !this.listView.list.childElements()[index].hasClassName('grouped'))
			{
				ids.push(this.data[index].id);
				
				this.listView.list.childElements()[parseInt(index)].setLoading();
			}
		}
		
		var ids_string = "";
		ids.each(function(id) {
			ids_string += "&id[]="+id;
		});
		
		new Ajax.Request(window.location.pathname+"ajax/untrash_item", {
			method: 'get',
			parameters: ids_string,
			onSuccess: function(transport) {
				this.loadData(this.currentPage);
			}.bind(this)
		});
	},

/**
 * UngroupedList#createSingleItemGroups() -> null
 * 
 * Create a group for each item currently selected (groups of 1)
 **/
	
	createSingleItemGroups: function()
	{
		var selected = this.listView.getSelectedIndexes();
				
		var ids = new Array();
		
		var valid = true;
		
		for(var index in selected)
		{					
			if(selected[index] && !this.listView.list.childElements()[index].hasClassName('grouped'))
			{
				ids.push(this.data[index].id);
				
				this.listView.list.childElements()[parseInt(index)].setLoading();
			}
			else
				valid = false
		}
		
		if(!valid)
		{
			for(var index in selected)
			{
				this.listView.list.childElements()[parseInt(index)].setLoading(false);
			}
			
			return;
		}
		
		var ids_string = "";
		ids.each(function(id) {
			ids_string += "&id[]="+id;
		});
		
		new Ajax.Request(window.location.pathname+"ajax/group_createsingles", {
			method: 'get',
			parameters: ids_string,
			onSuccess: function(transport) {
				transport.responseJSON.data.each(function(match){
					match.items.each(function(item){
						$$("."+item.id).each(function(elem){
							elem.setDisabled();
						}.bind(this));	
					}.bind(this));
				}.bind(this));
				
				// Should we add the new group to the grouped list?
				document.fire('group:added', transport.responseJSON.data);
			}.bind(this)
		});		
	},

/**
 * UngroupedList#groupSelected() -> null
 * 
 * Create a group from the selected items
 **/
	
	groupSelected: function()
	{
		var selected = this.listView.getSelectedIndexes();
				
		var ids = new Array();
		
		var valid = true;
		
		for(var index in selected)
		{					
			if(selected[index] && !this.listView.list.childElements()[index].hasClassName('grouped'))
			{
				ids.push(this.data[index].id);
				
				this.listView.list.childElements()[parseInt(index)].setLoading();
			}
			else
				valid = false
		}
		
		if(!valid)
		{
			for(var index in selected)
			{
				this.listView.list.childElements()[parseInt(index)].setLoading(false);
			}
			
			return;
		}
		
		var ids_string = "";
		ids.each(function(id) {
			ids_string += "&id[]="+id;
		});
		
		new Ajax.Request(window.location.pathname+"ajax/group_create", {
			method: 'get',
			parameters: ids_string,
			onSuccess: function(transport) {					
				transport.responseJSON.data[0].items.each(function(item){
					$$("."+item.id).each(function(elem){
						elem.setDisabled();
					}.bind(this));
				}.bind(this));
				
				// Should we add the new group to the grouped list?
				document.fire('group:added', transport.responseJSON.data);
			}.bind(this)
		});
	},
	
	updateTitle: function()
	{
		this.titleBar.update(Builder.node('div', {}, [
			(this.trashed?"Trashed ":"Ungrouped ")+this.currentPage.toUpperCase()+"'s ("+this.data.length+" items)"
		]));
	}
});